#include "CalMetricDataUtil.h"
// #include "SaveHexStringToFile.h"
#include <iostream>
#include <iomanip>
#include <sstream>
#include <chrono>
#include <cstring>
#include <algorithm>

float CalMetricDataUtil::totalDistance = 0.0f;
float CalMetricDataUtil::totalPower = 0.0f;
float CalMetricDataUtil::totalEnergy = 0.0f;
float CalMetricDataUtil::totalOutput = 0.0f;
int CalMetricDataUtil::totalRPM = 0;
int CalMetricDataUtil::rpmTimeCount = 0;
float CalMetricDataUtil::maxRPM = 0;
int64_t CalMetricDataUtil::startTime = 0;
int64_t CalMetricDataUtil::timeGap = 0;
int64_t CalMetricDataUtil::activeTime = 0;
int64_t CalMetricDataUtil::elapsedTime = 0;
std::string CalMetricDataUtil::res;
int64_t CalMetricDataUtil::lastUpdateTime = 0;
int64_t CalMetricDataUtil::cadenceZeroTime = 0;
const std::string CalMetricDataUtil::fileName = "save.bin";
const std::string CalMetricDataUtil::fileNameSE = "se_save.bin";

std::string CalMetricDataUtil::cal(const std::vector<int>& ans) {
    float instantaneousSpeed = ans[0] * 0.01f; // Km/h
    float instantaneousCadence = ans[1] * 0.5f; // RPM
    int resistanceLevel = ans[2]; // 阻力级别
    float instantaneousPower = ans[3]; // Watt

    int DefaultHeartRate = 100; // 默认心率

    auto now = std::chrono::system_clock::now().time_since_epoch();
    long currentTime = std::chrono::duration_cast<std::chrono::milliseconds>(now).count();

    if (lastUpdateTime == 0) {
        lastUpdateTime = currentTime;
        timeGap = 1000;
        elapsedTime = 1000;
        activeTime = 1000;
    } else {
        timeGap = (currentTime - lastUpdateTime);
        lastUpdateTime = currentTime;
        elapsedTime += timeGap;
        if(instantaneousCadence != 0 && instantaneousSpeed != 0){
            activeTime += timeGap;
        }
    }

    // 更新总RPM和RPM时间计数
    totalRPM += instantaneousCadence;
    rpmTimeCount++;

    // 计算每秒的距离（米）
    float distanceInSecond = instantaneousSpeed / 3600 * 1000;
    totalDistance += distanceInSecond;

    // 更新总功率
    totalPower += instantaneousPower;

    // 计算每秒能量输出
    float output = instantaneousPower * 1 / 1000;
    totalOutput += output;

    // 计算能量 (kcal)
    float energy = output / 4.186f / 0.22f;
    totalEnergy += energy;

    // 计算最大RPM
    if (instantaneousCadence > maxRPM) {
        maxRPM = instantaneousCadence;
    }

    // 计算平均速度 (Km/h)
    float activeTimeInHours = activeTime / 3600000.0f; // 转换为小时
    float elapsedTimeInHours = elapsedTime / 3600000.0f; // 转换为小时
    float avgSpeed = totalDistance / (activeTimeInHours * 1000);

    // 计算平均踏频 (RPM)
    float avgCadence = totalRPM / rpmTimeCount;

    // 计算平均功率 (Watt)
    float avgPower = totalPower / (activeTime / 1000.0f); // 转换为秒

    // 计算每小时能量 (kcal/h)
    float energyPerHour = totalEnergy / elapsedTimeInHours;

    // 计算每小时输出 (KJ/h)
    float outputPerHour = totalOutput / elapsedTimeInHours;

    // 创建一个字节缓冲区来存储这些数据
    char buffer[76];
    std::memset(buffer, 0, sizeof(buffer));
    float* floatPtr = reinterpret_cast<float*>(buffer);

    // 将数据放入缓冲区
    floatPtr[0] = instantaneousSpeed;
    floatPtr[1] = avgSpeed;
    floatPtr[2] = instantaneousCadence;
    floatPtr[3] = avgCadence;
    floatPtr[4] = distanceInSecond;
    floatPtr[5] = totalDistance;
    floatPtr[6] = static_cast<float>(resistanceLevel);
    floatPtr[7] = instantaneousPower;
    floatPtr[8] = totalPower;
    floatPtr[9] = avgPower;
    floatPtr[10] = energy;
    floatPtr[11] = totalEnergy;
    floatPtr[12] = energyPerHour;
    floatPtr[13] = outputPerHour;
    floatPtr[14] = output;
    floatPtr[15] = totalOutput;
    floatPtr[16] = maxRPM;
    floatPtr[17] = static_cast<float>(DefaultHeartRate);
    floatPtr[18] = elapsedTime;

    // 转换为十六进制字符串
    std::stringstream ss;
    for (int i = 0; i < sizeof(buffer); ++i) {
        ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(static_cast<unsigned char>(buffer[i]));
        if (i % 2 == 1) {
            ss << " ";
        }
    }
    res.append(ss.str()).append("\n");
    // std::cout << "res: " + res ;
    std::cout << std::dec << "activeTime: " << activeTime << std::endl;
    std::cout << std::dec << "elapsedTime: " << elapsedTime << std::endl;
    // SaveHexStringToFile::saveHexStringToFile(res, fileName);

    return parseHexStringToJson(ss.str());
}

std::string CalMetricDataUtil::parseHexStringToJson(const std::string& hexString) {
    std::string cleanedHexString = hexString;
    cleanedHexString.erase(std::remove(cleanedHexString.begin(), cleanedHexString.end(), ' '), cleanedHexString.end());
    // Remove all spaces from the string
    
    // 将十六进制字符串转换为字节数组
    size_t length = cleanedHexString.length();
    std::vector<char> byteRes(length / 2);
    for (size_t i = 0; i < length; i += 2) {
        byteRes[i / 2] = static_cast<char>(std::stoi(cleanedHexString.substr(i, 2), nullptr, 16));
    }

    // 创建一个 ByteBuffer 来转换字节数组为 float 数组
    std::vector<float> floatValues(byteRes.size() / 4);
    float* floatPtr = floatValues.data();
    std::memcpy(floatPtr, byteRes.data(), byteRes.size());

    // 创建 JSON 对象
    std::ostringstream json;
    json << "{";
    json << "\"unit\": \"KPH\",";
    json << "\"instantaneousSpeed\": \"" << std::fixed << std::setprecision(2) << floatValues[0] << "\",";
    json << "\"avgSpeed\": \"" << std::fixed << std::setprecision(2) << floatValues[1] << "\",";
    json << "\"instantaneousCadence\": \"" << std::fixed << std::setprecision(2) << floatValues[2] << "\",";
    json << "\"avgCadence\": \"" << std::fixed << std::setprecision(2) << floatValues[3] << "\",";
    json << "\"distanceInSecond\": \"" << std::fixed << std::setprecision(2) << floatValues[4] << "\",";
    json << "\"totalDistance\": \"" << std::fixed << std::setprecision(2) << floatValues[5] << "\",";
    json << "\"resistanceLevel\": \"" << std::fixed << std::setprecision(2) << floatValues[6] << "\",";
    json << "\"instantaneousPower\": \"" << std::fixed << std::setprecision(2) << floatValues[7] << "\",";
    json << "\"totalPower\": \"" << std::fixed << std::setprecision(2) << floatValues[8] << "\",";
    json << "\"avgPower\": \"" << std::fixed << std::setprecision(2) << floatValues[9] << "\",";
    json << "\"energy\": \"" << std::fixed << std::setprecision(2) << floatValues[10] << "\",";
    json << "\"totalEnergy\": \"" << std::fixed << std::setprecision(2) << floatValues[11] << "\",";
    json << "\"energyPerHour\": \"" << std::fixed << std::setprecision(2) << floatValues[12] << "\",";
    json << "\"outputPerHour\": \"" << std::fixed << std::setprecision(2) << floatValues[13] << "\",";
    json << "\"output\": \"" << std::fixed << std::setprecision(2) << floatValues[14] << "\",";
    json << "\"totalOutput\": \"" << std::fixed << std::setprecision(2) << floatValues[15] << "\",";
    json << "\"maxRPM\": \"" << std::fixed << std::setprecision(2) << floatValues[16] << "\",";
    json << "\"HeartRate\": \"" << std::fixed << std::setprecision(2) << floatValues[17] << "\",";
    json << "\"elapsedTime\": \"" << std::fixed << std::setprecision(2) << floatValues[18] << "\"";
    json << "}";

    // SaveHexStringToFile::saveHexStringToFile(json.str(), fileNameSE);

    return json.str();
}
